home *** CD-ROM | disk | FTP | other *** search
/ Die Speccy' 97 / Die Speccy' 97.iso / amiga_system / the_aminet / util / libs / halt.lzh / halt / halt_library.c < prev    next >
C/C++ Source or Header  |  1995-10-06  |  5KB  |  235 lines

  1. /*
  2.    halt_library.c --- halt library interface.
  3.  
  4.    (c) Copyright 1995 SHW Wabnitz
  5.    Written by Bernhard Fastenrath (fasten@shw.com)
  6.  
  7.    This file may be distributed under the terms
  8.    of the GNU General Public License.
  9. */
  10.  
  11. #if defined (__GNUC__)
  12. #include <stabs.h>
  13. #endif
  14.  
  15. #include "halt_library.h"
  16.  
  17. struct ExecBase *SysBase = NULL;
  18. struct DosLibrary *DOSBase = NULL;
  19. struct Library *HaltBase = NULL;
  20. struct List Clients;
  21. ULONG ClientsListBusy = 0;
  22.  
  23. #if defined (__GNUC__)
  24. const BYTE LibName[] = "halt.library";
  25. const BYTE LibIdString[] = "$VER: halt.library 2.0 (10-6-95)";
  26. const UWORD LibVersion = 2;
  27. const UWORD LibRevision = 0;
  28. #endif
  29.  
  30. #if defined (__GNUC__)
  31. #define LIBRT
  32. #define REG_a6
  33. #define REG_d1
  34. #define STRUCT_MYLIB struct Library
  35. #else
  36. #define LIBRT __saveds __asm
  37. #define REG_a6 register __a6
  38. #define REG_d1 register __d1
  39. #define ADDTABL_1(name,arg1);
  40. #define ADDTABL_END();
  41. #define STRUCT_MYLIB struct MyLibrary
  42. #endif
  43.  
  44. static void
  45. cleanup (void)
  46. {
  47.   if (DOSBase)
  48.     CloseLibrary ((struct Library *) DOSBase);
  49.   DOSBase = NULL;
  50. }
  51.  
  52. int LIBRT
  53. __UserLibInit (REG_a6 STRUCT_MYLIB *libbase)
  54. {
  55.   SysBase = *(struct ExecBase **)4;
  56.   HaltBase = (struct Library *) libbase;
  57.  
  58.   if (!(DOSBase = (struct DosLibrary *) OpenLibrary ("dos.library", 37)))
  59.     return 1;
  60.   NewList (&Clients);
  61.   return 0; /* success */
  62. }
  63.  
  64. void LIBRT
  65. __UserLibCleanup (REG_a6 STRUCT_MYLIB *libbase)
  66. {
  67.   cleanup ();
  68. }
  69.  
  70. ADDTABL_1(LIBReboot,d1);
  71.  
  72. int LIBRT
  73. LIBReboot (REG_d1 int flags)
  74. {
  75.   if (flags)
  76.   {
  77.     Disable ();
  78.     while (1);
  79.   }
  80.   ColdReboot ();
  81.   return 1;
  82. }
  83.  
  84. ADDTABL_1(LIBUnmount,d1);
  85.  
  86. int LIBRT
  87. LIBUnmount (REG_d1 char *filesystem)
  88. {
  89.   return unmount (NULL, filesystem);
  90. }
  91.  
  92. ADDTABL_1(LIBAddShutdownPort,d1);
  93.  
  94. int LIBRT
  95. LIBAddShutdownPort (REG_d1 MsgPort *prt)
  96. {
  97.   ShutdownClient *scl;
  98.  
  99.   if (((struct Process *) prt -> mp_SigTask) -> pr_WindowPtr != (void *) -1)
  100.     return 0;
  101.  
  102.   if (!(scl = (ShutdownClient *) AllocMem (sizeof (ShutdownClient), MEMF_PUBLIC)))
  103.     return 0;
  104.  
  105.   scl -> port = prt;
  106.   scl -> done = 0;
  107.   Forbid ();
  108.   AddHead (&Clients, (Node *) scl);
  109.   Permit ();
  110.   return 1;
  111. }
  112.  
  113. ADDTABL_1(LIBRemShutdownPort,d1);
  114.  
  115. int LIBRT
  116. LIBRemShutdownPort (REG_d1 MsgPort *prt)
  117. {
  118.   MinNode *mln;
  119.   int ret = 0;
  120.  
  121.   Forbid ();
  122.   for (mln = (MinNode *) Clients.lh_Head; mln -> mln_Succ; mln = mln -> mln_Succ)
  123.     if (((ShutdownClient *) mln) -> port == prt)
  124.     {
  125.       if (ClientsListBusy)
  126.     ((ShutdownClient *) mln) -> done = 1;
  127.       else
  128.       {
  129.         Remove ((Node *) mln);
  130.     FreeMem (mln, sizeof (ShutdownClient));
  131.       }
  132.       ret = 1;
  133.       break;
  134.     }
  135.   Permit ();
  136.   return ret;
  137. }
  138.  
  139. ADDTABL_1(LIBShutdownStatus,d1);
  140.  
  141. int LIBRT
  142. LIBShutdownStatus (REG_d1 ShutdownMessage *smsg)
  143. {
  144.   ShutdownClient *scl, *next;
  145.   ULONG abortable = 0;
  146.   MsgPort *prt;
  147.   Task *me;
  148.   ULONG mp_mask, mask, rmask;
  149.  
  150.   smsg -> sm_Context -> sc_rMask = 0;
  151.   smsg -> sm_Context -> sc_Port = NULL;
  152.  
  153.   if (IsListEmpty (&Clients))
  154.     return 1;
  155.  
  156.   me = FindTask (0);
  157.   prt = smsg -> sm_Msg.mn_ReplyPort;
  158.   if (smsg -> sm_Status != SHUTDOWN_HALT &&
  159.       smsg -> sm_Status != SHUTDOWN_ABORT &&
  160.       smsg -> sm_Status != SHUTDOWN_UMOUNT)
  161.   {
  162.     abortable = smsg -> sm_Flags & SDMF_ABORTABLE;
  163.   }
  164.   Forbid ();
  165.   ClientsListBusy ++;
  166.   Permit ();
  167.   mp_mask = 1 << prt -> mp_SigBit;
  168.   mask = mp_mask | SIGBREAKF_CTRL_C | smsg -> sm_Context -> sc_Mask;
  169.  
  170.   scl = (ShutdownClient *) Clients.lh_Head;
  171.   while (next = (ShutdownClient *) scl -> node.mln_Succ)
  172.   {
  173.     if (scl -> done)
  174.     {
  175.       Forbid ();
  176.       if (ClientsListBusy == 1)
  177.       {
  178.         Remove ((Node *) scl);
  179.         FreeMem (scl, sizeof (ShutdownClient));
  180.       }
  181.       Permit ();
  182.     }
  183.     else
  184.     {
  185.       if (scl -> port -> mp_SigTask != me)
  186.       {
  187.         PutMsg (scl -> port, (Message *) smsg);
  188.     for (;;)
  189.         {
  190.       if ((rmask = Wait (mask)) & mp_mask)
  191.       {
  192.         if (GetMsg (prt) == (Message *) smsg)
  193.           break;
  194.         else
  195.           smsg -> sm_Context -> sc_TimeOuts --;
  196.           }
  197.           if (rmask & SIGBREAKF_CTRL_C)
  198.       {
  199.         smsg -> sm_Flags |= (SDMF_CANCEL | SDMF_CTRL_C);
  200.         smsg -> sm_Context -> sc_Port = scl -> port;
  201.         smsg -> sm_Context -> sc_TimeOuts ++;
  202.         break;
  203.           }
  204.           if (rmask & smsg -> sm_Context -> sc_Mask)
  205.       {
  206.         /* Usually this is a timeout so we put the nasty
  207.            program at the end of the list.
  208.         */
  209.         Remove ((Node *) scl);
  210.         AddTail (&Clients, (Node *) scl);
  211.         smsg -> sm_Flags |= SDMF_SIG_MASK;
  212.         smsg -> sm_Context -> sc_Port = scl -> port;
  213.         smsg -> sm_Context -> sc_TimeOuts ++;
  214.         break;
  215.           }
  216.         }
  217.     if (abortable && smsg -> sm_Flags & (SDMF_CANCEL | SDMF_SIG_MASK))
  218.           break;
  219.       }
  220.     }
  221.     scl = next;
  222.   }
  223.   smsg -> sm_Context -> sc_rMask = rmask;
  224.   if (!abortable)
  225.     smsg -> sm_Flags &= ~(SDMF_CANCEL | SDMF_CTRL_C);
  226.  
  227.   Forbid ();
  228.   ClientsListBusy --;
  229.   Permit ();
  230.   return 1;
  231. }
  232.  
  233. ADDTABL_END();
  234.  
  235.